#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>

using namespace std;

__thread int cnt = 1;

void *thread_task(void *)
{
    printf("thread: 0x%x, cnt = %d, &cnt = %p\n", pthread_self(), cnt, &cnt);
    ++cnt;
    return nullptr;
}

int main()
{
    vector<pthread_t> tids;
    for (int i = 1; i <= 3; i++)
    {
        pthread_t tid;

        pthread_create(&tid, nullptr, thread_task, nullptr);

        tids.push_back(tid);
        sleep(1);
    }

    for (int i = 0; i < tids.size(); i++)
    {
        pthread_join(tids[i], nullptr);
    }

    return 0;
}

// 线程之间没有密码，因为它们共享同一个进程地址空间~
// int *p = nullptr; // 获取第一个线程中的变量stack_tmp

// string toHex(pthread_t t)
// {
//     char buffer[64];
//     snprintf(buffer, sizeof(buffer), "0x%x", t);
//     return buffer;
// }

// struct threadData
// {
//     string threadname;
// };

// void InitThreadData(threadData *td, int number)
// {
//     td->threadname = "thread-" + to_string(number);
// }

// void *thread_task(void *args)
// {
//     threadData *td = (threadData *)args;

//     int stack_tmp = 1;
//     if (td->threadname == "thread-2")
//     {
//         p = &stack_tmp;
//     }
//     while (true)
//     {
//         cout << "线程名字：" << td->threadname
//              << ", 变量stack_tmp的地址: " << &stack_tmp
//              << ", stack_tmp = " << stack_tmp << endl;
//         sleep(1);
//     }

//     return nullptr;
// }

// int main()
// {
//     vector<pthread_t> tids;
//     for (int i = 1; i <= 3; i++)
//     {
//         pthread_t tid;

//         threadData *td = new threadData;
//         InitThreadData(td, i);

//         pthread_create(&tid, nullptr, thread_task, (void *)td);

//         tids.push_back(tid);
//         sleep(1);
//     }

//     sleep(1);
//     cout << "main thread get a thread local value, val: " << *p << ", &val: " << p << endl;

//     for (int i = 0; i < tids.size(); i++)
//     {
//         pthread_join(tids[i], nullptr);
//     }

//     return 0;
// }

// 验证独立栈
// void *thread_task(void *)
// {
//     int stack_tmp = 1;
//     printf("线程id: 0x%x, 变量stack_tmp的地址: %p\n", pthread_self(), &stack_tmp);
//     return nullptr;
// }

// int main()
// {
//     vector<pthread_t> tids;

//     for (int i = 1; i <= 5; i++)
//     {
//         pthread_t tid;
//         /*
//             注：如果要给pthread_create的第四个参数传对象
//                 不能传for循环中的对象。因为当第一次for循环结束后，
//                 for循环内的对象销毁，那么第一个线程参数的指针就会指向
//                 已经销毁的对象，造成野指针！
//         */
//         pthread_create(&tid, nullptr, thread_task, nullptr);
//         tids.push_back(tid);
//         sleep(1);
//     }

//     for (int i = 0; i < tids.size(); i++)
//     {
//         pthread_join(tids[i], nullptr);
//     }

//     return 0;
// }

// 线程ID
// void *thread_task(void *)
// {
//     while (true)
//     {
//         printf("new thread say: My id is %x\n", pthread_self());
//         sleep(1);
//     }
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, thread_task, nullptr);

//     printf("main thread say: new thread id is %x\n", tid);

//     pthread_join(tid, nullptr);

//     return 0;
// }
